package com.work.order.service.impl;

import com.work.order.feign.AccountFeignClient;
import com.work.order.feign.StockFeignClient;
import com.work.order.model.Order;
import com.work.order.repository.OrderDAO;
import com.work.order.service.IOrderService;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**
 * demo模板来源于官网，此处进行了改造
 *
 * @author 猿仁
 * @date 2023/3/11 20:18
 */
@Slf4j
@Service

public class OrderServiceImpl implements IOrderService {

    @Resource
    private AccountFeignClient accountFeignClient;
    @Resource
    private StockFeignClient stockFeignClient;
    @Resource
    private OrderDAO orderDAO;

    /**
     * 下单：创建订单、减库存，涉及到两个服务
     *
     * @param userId
     * @param commodityCode
     * @param count
     * @param tag commit接口如果入参是[成功]，不抛出异常，[失败]，抛出异常
     */
    @Override

    public void placeOrder(String userId, String commodityCode, Integer count,String tag) {
        log.info("OrderService XID = {}", RootContext.getXID());
        BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5));
        Order order = new Order().setUserId(userId).setCommodityCode(commodityCode).setCount(count).setMoney(
                orderMoney);
        orderDAO.insert(order);

        // stock服务未报错，order服务报错
        try {
            stockFeignClient.deduct(commodityCode, count);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        // 输入commit接口
        if("product-1".equals(commodityCode) && tag.equals("失败")){
            throw new RuntimeException("订单业务处理异常...");
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(String userId, String commodityCode, Integer count) {

        BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5));

        Order order = new Order().setUserId(userId).setCommodityCode(commodityCode).setCount(count).setMoney(
                orderMoney);
        orderDAO.insert(order);

        accountFeignClient.reduce(userId, orderMoney);

    }

    @Override
    public boolean busCommit(BusinessActionContext actionContext) {
        log.info("busCommit xid = " + actionContext.getXid() + "提交成功");
        // todo 若一阶段资源预留，这里则要提交资源
        return true;
    }

    @Override
    public boolean busRollback(BusinessActionContext actionContext) {
        // todo 这里写中间件、非关系型数据库的回滚操作
        log.info("please manually rollback this data:" + actionContext.getActionContext("userId"));
        log.info("actionContext:" + actionContext);
        return true;
    }
}
